#    Copyright 2008, 2009, 2011, 2012 Tri-County Electric Cooperative, St. Matthews, South Carolina
#    This file is part of COOPIP.
#    COOPGIS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    COOPIP is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with COOPIP.  If not, see <http://www.gnu.org/licenses/>.


#TO Inspect a database:
#Run python manage.py inspectdb --database "databasename" > raw.sql
#For example:
#python manage.py inspectdb --database gis > RawGIS.sql
DatabaseName='OMS' #Choices are 'GIS', 'AMR', 'CIS',      #'GOS' is deprecated.   'OMS'  --switch to admin login?  




def PostProcess(i):
    i = i.replace('# =', '=')
    i = i.replace('decimal_places=-127', 'decimal_places=5')
    i = i.replace('max_digits=0', 'max_digits=15')
    i = i.replace('primary_key=Truedb_column=', 'primary_key=True, db_column=')
    if(using == 'amr'):
        i = i.replace('.DateField(', '.DateTimeField(')
    if(using == 'oms'):
        if('"(models.Model):' in i):
            i= i.replace('"."', "").replace('"', '')

    return i




#************************BEGIN Add Include Files to Path************************
import sys
IncludePath="/opt/coopip/djangoproject/include"
if(not IncludePath in sys.path):
    sys.path.append(IncludePath)


    
#************************END   Add Include Files to Path************************
from django.contrib.gis.geos import *
import os, time, psycopg2, datetime

#********************Setup psycopg2 and django section********************
PathDjangoRoot="/opt/coopip/"
if(not PathDjangoRoot in sys.path):
    sys.path.append(PathDjangoRoot)
from django.core.management import setup_environ
import djangoproject.settings
setup_environ(djangoproject.settings)
from djangoproject.models import *
from django.contrib.gis.geos import GEOSGeometry
from django.db import transaction
#********************Setup psycopg2 and django section********************






import django.db



InputFileName='/opt/coopip/djangoproject/Raw' + str(DatabaseName) + '.py'
OutputFileName='/opt/coopip/djangoproject/' + str(DatabaseName) + '2.py'
using=DatabaseName.lower()

#import GIS
InputFile=open(InputFileName, 'r')
OutputFile=open(OutputFileName, 'w')

Rows=InputFile.readlines()
FirstAttributeRowIndicator=False
TableNameDict={}
InMemoryList=[]
for row in Rows:
    InMemoryList.append(row)
InputFile.close()


#PrePreprocess OMS to accomdate errors in the Introspection hacks to support schemas

#Preprocess the list, putting the table names into TableNameDict (keys are class names)
for row in InMemoryList:
    if(row[:5] == 'class'):
        Key=row[5:row.find('(')]
    if("db_table = u'" in row):
        Start=row.find("'") + 1
        End=row[Start:].find("'")
        TableNameDict[Key] = row[Start:][:End]
    if(using == 'oms'):
        if('db_table = \'"' in row):
            Start=row.find("'") + 1
            End=row[Start:].find("'")
            TableNameDict[Key] = row[Start:][:End]

    

ListOfClasses=[]

#Process the rows,putting the results into a List in the format [[RowCount, ClassName, Rows],[RowCount, ClassName, Rows]...]        
TempList=[]
for row in InMemoryList:
    if(row[:5] == 'class'):
        TempList=[]
        FirstAttributeRowIndicator=True
        Cursor=django.db.connections[using].cursor()
        ClassName=row[5:row.find('(')]
        OldClassNameToPossiblyReplace=row[:5] + ClassName

        try:
            if(using == 'gis'):
                Cursor.execute('select count(*) from "' + TableNameDict[ClassName] + '";')
            else:
                Cursor.execute('select count(*) from ' + TableNameDict[ClassName])
            RowCount=Cursor.fetchall()[0][0]
            TempList.append('#' + ClassName.strip() + ' had ' + str(RowCount) + ' rows.\n')
            print "ADDING:     " + str(TableNameDict[ClassName]).ljust(40)  + str(RowCount) 
        except django.db.utils.DatabaseError:
            RowCount = -1
            print "Skipping:  " + str(TableNameDict[ClassName])
            TempList.append('#' + ClassName.strip() + ' had ' + 'UNKNOWN NUMBER OF ROWS, AN EXCEPTION OCCURRED' + ' rows.\n')
    

        if(ClassName[1] in '0123456789'):
            row=row.replace(OldClassNameToPossiblyReplace, 'class a' + ClassName[1:])
        if(using == 'gis'):
            if('class Substation(' in row):
                row = row.replace('Substation', 'Coopgissubstation')
        row = row.replace('$', '') #Remove Dollarsigns from class names
        TempList.append(row)
    elif(FirstAttributeRowIndicator):
        FirstAttributeRowIndicator=False
        TempList.append("    using = '" + using + "'\n")  
        if('primary_key' in row):
            TempList.append(row)
        elif('max_length=' in row or 'null=' in row or 'decimal_places=' in row or 'blank=' in row):
            TempList.append(row[:row.find('(')+1] + 'primary_key=True, ' + row[row.find('(')+1:])
        else:
            TempList.append(row[:row.find('(')+1] + 'primary_key=True' + row[row.find('(')+1:])
        if('primary_key' in TempList[len(TempList)-1]):
            TempList[len(TempList)-1] = TempList[len(TempList)-1].replace(', null=True', '').replace(', blank=True', '')
    elif('db_table = ' in row):
        TempList.append(row)
        TempList.append("        app_label='djangoproject'\n")
        ListOfClasses.append([RowCount, ClassName.strip(), TempList])
        TempList=[]
    elif('models.ForeignKey(' in row):
        Start = row.find('ForeignKey(') + len('ForeignKey(')
        End=row.find(',')
        if(End == -1):
            End=row.find(')')
        FieldNameEnd=row.find('=')
        FieldName=row[:FieldNameEnd].strip()
        ForeignKeyName=row[Start:End].strip()
        TempList.append(row[:Start] + "'" + row[Start:End] + "'" + ',' + ' related_name="' + ClassName.strip() + '_' + FieldName + '"' + row[End:])
    elif('BooleanField' in row and 'null=True' in row):
        TempList.append(row.replace('models.BooleanField', 'models.NullBooleanField'))
    else:
        TempList.append(row)
        


OutputFile.write("""#    Copyright 2012 Tri-County Electric Cooperative, St. Matthews, South Carolina
#    This file is part of COOPGIS.
#    COOPGIS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    COOPGIS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with COOPGIS.  If not, see <http://www.gnu.org/licenses/>.

import os, csv, shutil, datetime, time, reportlab
from django.contrib.gis.db import models
from django.http import HttpResponse
from django.contrib import admin

""")

        



ListOfClasses.sort(key=lambda i: i[1])

for row in ListOfClasses:
    if(row[0] == 0):
        continue
    OutputFile.write('\n')
    for i in row[2]:
        OutputFile.write(PostProcess(i))

OutputFile.write("""\n#******************************************************
#******************************************************
#******************************************************
#Entries Below this point had 0 rows at the time the models file was created.\n
#******************************************************
#******************************************************
#******************************************************\n""")


for row in ListOfClasses:
    if(row[0] > 0):
        continue
    OutputFile.write('\n')
    for i in row[2]:
        OutputFile.write(PostProcess(i))



OutputFile.close()




    


#**************************************
#NOTE FOR ORACLE INSPECT DB
#As of Django 1.4, Inspectdb is not fully supported for Oracle
#This custom inspectdb code should be placed in the introspection.py file, replacing the function there
#Use the --verbosity 3 argument when running to get the error messages to print
def get_table_list(self, cursor):
    "Returns a list of table names in the current database."
    import sys
    cursor.execute("SELECT table_name from all_all_tables") #This modification was made by Gregory Roby groby 10/19/2012
    TempList=[]
    for row in cursor.fetchall():
        TempList.append(row[0].lower()) 
    FilteredList=[]
    sys.stderr.write('\n')
    for row in TempList:
       try:
           cursor.execute("SELECT count(*) from " + str(row))
           a = cursor.fetchall()
           sys.stderr.write('ADDING:      ' + str(row + '\n'))
           FilteredList.append(row)    
       except:
           sys.stderr.write('SKIPPING:    ' + str(row + '\n'))
       sys.stderr.write('\n')
    return FilteredList
#**************************************
#This class replaces the class in the gis introspection.py file for the Oracle backend

#class OracleIntrospection(DatabaseIntrospection):
#    # Associating any OBJECTVAR instances with GeometryField.  Of course,
#    # this won't work right on Oracle objects that aren't MDSYS.SDO_GEOMETRY,
#    # but it is the only object type supported within Django anyways.
#    data_types_reverse = DatabaseIntrospection.data_types_reverse.copy()
#    data_types_reverse[cx_Oracle.OBJECT] = 'GeometryField'
#
#    def get_geometry_type(self, table_name, geo_col):
#        cursor = self.connection.cursor()
#        try:
#            # Querying USER_SDO_GEOM_METADATA to get the SRID and dimension information.
#            try:
#                cursor.execute('SELECT "DIMINFO", "SRID" FROM "USER_SDO_GEOM_METADATA" WHERE "TABLE_NAME"=%s AND "COLUMN_NAME"=%s',
#                               (table_name.upper(), geo_col.upper()))
#                row = cursor.fetchone()
#            except Exception, msg:
#                raise Exception('Could not find entry in USER_SDO_GEOM_METADATA corresponding to "%s"."%s"\n'
#                                'Error message: %s.' % (table_name, geo_col, msg))
#
#            # TODO: Research way to find a more specific geometry field type for
#            # the column's contents.
#            field_type = 'GeometryField'
#
#           # Getting the field parameters.
#            field_params = {}
#            try:
#                dim, srid = row
#            except:
#                dim = 2
#                srid= 4326
#            if srid != 4326:
#                field_params['srid'] = srid
#            # Length of object array ( SDO_DIM_ARRAY ) is number of dimensions.
#            try:
#                dim = len(dim)
#            except:
#                dim=2
#            try:
#                if dim != 2:
#                    field_params['dim'] = dim
#            except: 
#                pass
#        finally:
#            cursor.close()




